package edu.yctc.origin.service.impl;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Service;

import edu.yctc.origin.constant.ResultCode;
import edu.yctc.origin.dao.UserDAO;
import edu.yctc.origin.entity.ResultDO;
import edu.yctc.origin.entity.UserDO;
import edu.yctc.origin.service.UserIService;
import edu.yctc.origin.utils.CommonUtils;
import edu.yctc.origin.utils.SHA256Util;

/**
 * userService实现类
 * 
 * @author 赵宜珺
 */
@ComponentScan({"edu.yctc.origin.dao"})
@Service("userService")
public class UserServiceImpl implements UserIService {

    private final static Logger LOG = LoggerFactory.getLogger("serviceLogger");

    @Resource
    private UserDAO userDAO;

    @Override
    public ResultDO<Long> signin(UserDO userDO) {
        // 检验参数
        if (StringUtils.isBlank(userDO.getNumber()) || StringUtils.isBlank(userDO.getPassword())) {
            LOG.error("signin fail, parameter invalid, userDO={}", userDO);
            return new ResultDO<Long>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
        }
        try {
            UserDO check = null;
            // 如果是邮箱登陆
            if (CommonUtils.isEmailAddress(userDO.getNumber())) {
                check = userDAO.getUserDOByMailAndPassword(userDO.getNumber(), SHA256Util.SHA256(userDO.getPassword()));
            } else {
                check =
                    userDAO.getUserDOByNumberAndPassword(userDO.getNumber(), SHA256Util.SHA256(userDO.getPassword()));
            }
            if (check == null) {
                LOG.error("signin fail, no such user, userDO={}", userDO);
                return new ResultDO<Long>(false, ResultCode.INCORRECT_NUMBER_OR_PASSWORD,
                    ResultCode.MSG_INCORRECT_NUMBER_OR_PASSWORD, null);
            }
            LOG.info("signin success, userDO={}", userDO);
            return new ResultDO<Long>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, check.getId());
        } catch (Exception e) {
            LOG.error("signin error, userDO={}", userDO, e);
            return new ResultDO<Long>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION,
                null);
        }
    }

    @Override
    public ResultDO<UserDO> getUserDOById(long id) {
        if (id <= 0) {
            LOG.error("get userDO by id fail, parameter invalid, id={}", id);
            return new ResultDO<UserDO>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID, null);
        }
        try {
            UserDO userDO = userDAO.getUserDOById(id);
            if (userDO == null) {
                LOG.error("get userDO by id fail, no such user, id={}", id);
                return new ResultDO<UserDO>(false, ResultCode.NO_SUCH_USER, ResultCode.MSG_NO_SUCH_USER, null);
            }
            LOG.info("get userDO by id success, id={}", id);
            return new ResultDO<UserDO>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, userDO);
        } catch (Exception e) {
            LOG.error("get userDO by id error, id={}", id, e);
            return new ResultDO<UserDO>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION,
                null);
        }
    }

    @Override
    public ResultDO<Void> updatePassword(UserDO userDO, String oldPassword, String newPassword) {
        try {
            UserDO userDOTemp = userDAO.getUserDOByNumberAndPassword(userDO.getNumber(),
                SHA256Util.SHA256(oldPassword));
            if (userDOTemp == null) {
                // 老密码核验错误
                LOG.info("user oldPassword wrong, userDO={}, oldPassword={}, newPassword={}", userDO, oldPassword,
                    newPassword);
                return new ResultDO<>(false, ResultCode.PASSWORD_ERROR, ResultCode.MSG_PASSWORD_ERROR);
            }
            userDOTemp.setPassword(SHA256Util.SHA256(newPassword));
            userDAO.update(userDOTemp);
            LOG.info("update password success,userDO={}", userDO);
            return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS);
        } catch (Exception e) {
            LOG.info("updatePassword error,userDO={}", userDO, e);
            return new ResultDO<>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION);
        }
    }

    @Override
    public ResultDO<UserDO> getUserDOByMail(String mail) {
        try {
            UserDO userDO = userDAO.getUserDOByMail(mail);
            if (userDO == null) {
                LOG.error("get userDO by mail fail, no such user, mail={}", mail);
                return new ResultDO<UserDO>(false, ResultCode.NO_SUCH_USER, ResultCode.MSG_NO_SUCH_USER, null);
            }
            LOG.info("get userDO by mail success,  mail={}", mail);
            return new ResultDO<UserDO>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS, userDO);
        } catch (Exception e) {
            LOG.error("get userDO by mail error", e);
            return new ResultDO<UserDO>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION,
                null);
        }
    }

    @Override
    public ResultDO<Void> retrievePasswordByMail(String mail, String newPassword) {
        try {
            if (StringUtils.isBlank(mail) || StringUtils.isBlank(newPassword)) {
                LOG.error("parameter illegal, mail={}, newPassword={}", mail, newPassword);
                return new ResultDO<>(false, ResultCode.PARAMETER_INVALID, ResultCode.MSG_PARAMETER_INVALID);
            }
            UserDO userDO = userDAO.getUserDOByMail(mail);
            if (userDO == null) {
                LOG.error("retrievePassWordByMail fail, no such userDO, mail={}, userDO={}", mail, userDO);
                return new ResultDO<>(false, ResultCode.NO_SUCH_USER, ResultCode.MSG_NO_SUCH_USER);
            }
            userDO.setPassword(SHA256Util.SHA256(newPassword));
            userDAO.update(userDO);
            return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS);
        } catch (Exception e) {
            LOG.info("retrieve password by mail error", e);
            return new ResultDO<>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION);
        }
    }

    @Override
    public ResultDO<Void> updateMail(UserDO userDO, String mail) {
        try {
            UserDO userDOTemp = userDAO.getUserDOById(userDO.getId());
            if (userDOTemp == null) {
                LOG.info("user wrong, userDO={}, Mail={}", userDO, mail);
                return new ResultDO<>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION);
            }
            userDOTemp.setMail(mail);
            userDAO.update(userDOTemp);
            LOG.info("update mail success,userDO={}, Mail={}", userDO, mail);
            return new ResultDO<>(true, ResultCode.SUCCESS, ResultCode.MSG_SUCCESS);
        } catch (Exception e) {
            LOG.info("update mail error,userDO={}, Mail={}", userDO, mail, e);

            return new ResultDO<>(false, ResultCode.ERROR_SYSTEM_EXCEPTION, ResultCode.MSG_ERROR_SYSTEM_EXCEPTION);
        }
    }

}
